package com.makerworks.medu

import android.app.Activity
import android.app.AlertDialog
import android.bluetooth.BluetoothAdapter
import android.content.Intent
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.os.Handler
import android.provider.Settings
import android.util.DisplayMetrics
import android.util.Log
import android.view.*
import android.widget.*
import com.makerworks.medu.*
import com.makerworks.medu.SearchEvent
import kotlinx.android.synthetic.main.activity_connect.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.*

class ConnectActivity : Activity() {
    var SCREEN_WIDTH = 0
    var SCREEN_HEIGHT = 0

    object Obj {
        var instance: ConnectActivity? = null
        var hasShow: Boolean = false
    }

    private val REQUEST_ENABLE_BT = 2
    //    private var mDetectDistanceTimer: Timer? = null
    private val mHandler: Handler = Handler()
    private var isConnecting = false
    private var hasInit = false
    private var retryRequestCount = 0
    private var currentStep: Int = -1

    private var devicesListViewLayout: View? = null
    private var devicesListView: ListView? = null
    private var mDetectDistanceRunnable: Runnable? = null
    private var mTimeOutCancelRunnable: Runnable? = null
    private var lastClosestDevice: DeviceBean? = null
    private var deviceListPopupWindow: PopupWindow? = null
    private var isListMode = false
    private var devices: ArrayList<DeviceBean>? = null
    private var devicesListAdapter: BaseAdapter = object : BaseAdapter() {
        override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
            var view: View
            if (convertView == null) {
                view = layoutInflater.inflate(R.layout.devices_list_item, null)
            } else {
                view = convertView
            }
            val deviceItem: DeviceBean? = devices?.get(position)
            if (deviceItem != null) {
                if (deviceItem.distance > 0) {
                    val integer: Int = deviceItem.distance.toInt() //distance的整数部分
                    val fractional = ((deviceItem.distance - deviceItem.distance.toInt()) * 10).toInt()
                    val distanceString = "$integer.${fractional}m"
                    (view.findViewById(R.id.list_item_device_distance) as TextView).text = distanceString
                } else {
                    (view.findViewById(R.id.list_item_device_distance) as TextView).text = ""
                }
                val string = deviceItem.bluetoothDevice.name
                var nameString: String
                if (string.equals("Makeblock", ignoreCase = true) || string.equals("Makeblock_LE", ignoreCase = true)) {
                    nameString = "Makeblock"
                } else {
                    nameString = string.replace("Makeblock_LE", "").replace("Makeblock_", "")
                }

                (view.findViewById(R.id.list_item_device_name) as TextView).text = nameString
            }
            return view
        }

        override fun getItem(position: Int): Any {
            return devices!![position]
        }

        override fun getItemId(position: Int): Long {
            return position.toLong()
        }

        override fun getCount(): Int {
            return if (devices == null) 0 else devices!!.size
        }

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_connect)
        val dm = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(dm)
        SCREEN_WIDTH = Math.max(dm.widthPixels, dm.heightPixels)
        SCREEN_HEIGHT = Math.min(dm.widthPixels, dm.heightPixels)
        EventBus.getDefault().register(this)
        hasInit = false
        setupView()
        Obj.instance = this
    }

    private fun stopRunnable() {
        mHandler.removeCallbacks(mDetectDistanceRunnable)
        mHandler.removeCallbacks(mTimeOutCancelRunnable)
    }

    private fun resetRunnable() {
        mDetectDistanceRunnable = Runnable {
            if (isConnecting)
                return@Runnable
            if (isListMode) {
                var newDevices = BluetoothAdapter_BLE.getInstance().devices
                if (devicesListView == null && devicesListViewLayout != null) {
                    devices = newDevices
                    devicesListView = devicesListViewLayout!!.findViewById(R.id.connect_devices_list) as ListView?
                    devicesListView!!.adapter = devicesListAdapter
                    devicesListView!!.onItemClickListener = AdapterView.OnItemClickListener {
                        parent, view, position,
                        id ->
                        updateToStep(3)
                        if (!isConnecting) {
                            isConnecting = true
                            deviceListPopupWindow?.dismiss()
                            BluetoothAdapter_BLE.getInstance().connect(devices!![position])
                        }
                    }
                } else {
                    val newCount: Int = if (newDevices == null) 0 else newDevices.size
                    val oldCount: Int = devicesListAdapter.count
                    if (newCount != oldCount) {
                        devices = newDevices
                        devicesListAdapter.notifyDataSetChanged()
                    }
                }
            } else {
                //lyh 筛选指定时间内有更新距离,且信号强度高的设备
                val activeDevices = BluetoothAdapter_BLE.getInstance().devices
                        .filter { it.stableRssi >= -50 && System.currentTimeMillis() - it.updateTime < 5000 }
                var closestDevice: DeviceBean? = null
                var closerCount = 0
                var closestCount = 0
                for (item in activeDevices) {
                    when {
                        item.stableRssi >= -32 || item.rssi > -25 -> {
                            closestDevice = item
                            lastClosestDevice = item
                            ++closestCount
                            ++closerCount
                        }
                        else -> {
                            ++closerCount
                        }
                    }
                }

                updateState(closestCount, closerCount, closestDevice)
            }
            mHandler.postDelayed(mDetectDistanceRunnable, 200)
        }
        mDetectDistanceRunnable?.run()
        mTimeOutCancelRunnable = Runnable {
//            ControllerManager.cancelConnect()
            isConnecting = false
        }
    }

    private fun setupView() {
        connect_help.setOnClickListener { jumpToConnectGuide() }
        connect_list.setOnClickListener {
            showList()
            isListMode = true
        }
        connect_back.setOnClickListener { onBackPressed() }
    }

    override fun onBackPressed() {
        BluetoothConnectHelper.onPressBack()
        super.onBackPressed()
    }

    override fun onResume() {
        super.onResume()
        if (!hasInit || BluetoothAdapter_BLE.getInstance().isEnable) {
            mHandler.postDelayed({
                search_startDiscovery()
            }, 10)

        }
        updateToStep(1)
        hasInit = true
    }

    override fun onStop() {
        mHandler.removeCallbacks(mDetectDistanceRunnable)
        super.onStop()
    }

    /**
     * 为判断逻辑简单,closerCount 包含closestCount
     */
    fun updateState(closestCount: Int, closerCount: Int, closestDevice: DeviceBean?) {
        if (isConnecting)
            return
        when {
            closestCount == 1 -> {
//                只有一个设备最近,连接
                val stableRssi = closestDevice?.stableRssi
                updateToStep(3)
                if (stableRssi != null && stableRssi >= -32) {
                    if (!isConnecting) {
                        //开始连接
                        isConnecting = true
                        closestDevice?.rssi = -1000
                        BluetoothAdapter_BLE.getInstance().connect(closestDevice)
                    }
                }
            }
            closerCount > 0 -> {
                if (lastClosestDevice != null && lastClosestDevice!!.maxRssi >= -32) {
                    return
                }
                //范围内有1个以上设备(最近的设备有多个,或者没有)
                updateToStep(2)
            }
            else -> {
                //范围内没有设备
                updateToStep(1)
            }
        }
    }

    /**
     * 1 为初始状态, 2 为附近有设备, 3 为连接中, 4 为连接成功, 5 为连接失败(?)
     */
    private fun updateToStep(step: Int) {
        if (currentStep == step)
            return
        currentStep = step
        connect_step_1_2.visibility = when (step) {
            1, 2 -> View.VISIBLE
            else -> View.GONE
        }
        connect_step_2.visibility = when (step) {
            2 -> View.VISIBLE
            else -> View.GONE
        }
        connect_step_3_4_5.visibility = when (step) {
            3, 4, 5 -> View.VISIBLE
            else -> View.GONE
        }
        connect_step_3.visibility = when (step) {
            3 -> View.VISIBLE
            else -> View.GONE
        }

        connect_step_4_5.visibility = when (step) {
            4, 5 -> View.VISIBLE
            else -> View.GONE
        }

        connect_step_4_5_connect_img.setImageResource(when (step) {
            4 -> R.drawable.connect_connect
            5 -> R.drawable.connect_disconnect
            else -> 0
        })

        connect_step_4_5_connect_img.visibility = when (step) {
            4, 5 -> View.VISIBLE
            else -> View.GONE
        }

        connect_step_4_state_img.visibility = when (step) {
            4 -> View.VISIBLE
            else -> View.INVISIBLE
        }

        connect_textView.setText(when (step) {
            1 -> R.string.ble_close_device_android
            2 -> R.string.ble_device_found
            3 -> R.string.ble_connecting
            4 -> R.string.ble_connect_success
            5 -> R.string.ble_search_disconnected
            else -> R.string.ble_close_device_android
        })

        when (step) {
            3 -> {
                connect_step_3_dot0.startAnimation()
                connect_step_3_dot1.startAnimation()
                connect_step_3_dot2.startAnimation()
                connect_step_3_dot3.startAnimation()
                connect_step_3_dot4.startAnimation()
            }
            else -> {
                connect_step_3_dot0.stopAnimation()
                connect_step_3_dot1.stopAnimation()
                connect_step_3_dot2.stopAnimation()
                connect_step_3_dot3.stopAnimation()
                connect_step_3_dot4.stopAnimation()
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onBluetoothSearchEvent(event: SearchEvent) {
        when (event.eventType) {
            SearchEvent.CONNECT_START -> {
                //如果10秒没连接上,直接断连
                mHandler.removeCallbacks(mTimeOutCancelRunnable)
                mHandler.postDelayed(mTimeOutCancelRunnable, 10000)
            }
            SearchEvent.CONNECT_SUCCEED -> {
                if (isConnecting) {
                    isConnecting = false
                    finish()
                }
            }
            SearchEvent.CONNECT_DISCONNECTED -> {
                isConnecting = false
                BluetoothAdapter_BLE.getInstance().startDiscovery()
                mHandler.post({ search_startDiscovery() })
                stopRunnable()
                resetRunnable()
            }

            SearchEvent.CONNECT_FAIL -> {
                isConnecting = false
                stopRunnable()
                updateToStep(5)
                mHandler.postDelayed({
                    hasInit = false
                    onResume()
                }, 1000)
            }

            SearchEvent.OPEN_BLUETOOTH -> {
                //打开申请权限的Activity
                val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
                val cn = enableBtIntent.resolveActivity(this.packageManager)
                if (cn == null) {  //有的手机cn为null
                    //					throw new RuntimeException("RuntimeException: enableBtIntent.resolveActivity(context.getPackageManager())为null");
                    //无法弹出打开蓝牙的Activity，so 弹出提示框，让用户到android--->setting---->bluetooth中打开蓝牙
                    search_showGoToSettingDialog()
                } else {
                    try {
                        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
                        hasInit = false
                    } catch (e: Exception) {
                        e.printStackTrace()
                        search_showGoToSettingDialog()
                    }

                }
            }

        }


    }


//    @Subscribe(threadMode = ThreadMode.MAIN)
//    fun onConnectedOk(event: ConnectedOrChooseDeviceChangeEvent) {
//        when (ControllerManager.getConnectedState()) {
//            ControllerManager.Connected_Ok -> {
//                updateToStep(4)
//                mHandler.removeCallbacks(mRetryRequestVersionRunnable)
//                mHandler.removeCallbacks(mTimeOutCancelRunnable)
//                Handler().postDelayed({
//                    finish()
//                }, 500)
//            }
//        }
//    }

    fun search_startDiscovery() {
        //正在扫描中，return
        if (BluetoothAdapter_BLE.getInstance().isDiscovering!!) {
            return
        }
        //重新扫描
        stopRunnable()
        resetRunnable()
        BluetoothAdapter_BLE.getInstance().startDiscovery()
    }

    //弹出提示框：提示用户到手动打开蓝牙
    private fun search_showGoToSettingDialog() {
        AlertDialog.Builder(this).setTitle(R.string.ble_setting_open).setPositiveButton(R.string.control_confirm) { dialog, which -> startActivity(Intent(Settings.ACTION_BLUETOOTH_SETTINGS)) }.setNegativeButton(R.string.control_cancel, null).show()
    }

    public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == REQUEST_ENABLE_BT) {
            if (resultCode == RESULT_OK) {
            } else if (resultCode == RESULT_CANCELED) {
            }
        }
    }

    private fun jumpToConnectGuide() {
        startActivity(Intent(this, ConnectGuideBleActivity::class.java))
    }

    override fun finish() {
        EventBus.getDefault().unregister(this)
        mHandler.removeCallbacks(mTimeOutCancelRunnable)
        Obj.instance = null
        Obj.hasShow = false
        super.finish()
    }


    private fun showList() {
        val height = getPercentWidthToPx(715.0f / 1920)
        val width = getPercentHeightToPx(812.0f / 1080)
        if (deviceListPopupWindow == null) {
            devicesListViewLayout = layoutInflater.inflate(R.layout.popup_devices_list, null)
            devicesListViewLayout?.findViewById(R.id.connect_refresh_list)?.setOnClickListener {
                search_startDiscovery()
                mDetectDistanceRunnable?.run()
            }
            deviceListPopupWindow = PopupWindow(devicesListViewLayout, width, height, true)
            deviceListPopupWindow!!.isTouchable = true
            deviceListPopupWindow!!.isOutsideTouchable = true
            deviceListPopupWindow!!.setBackgroundDrawable(BitmapDrawable(resources))
            deviceListPopupWindow!!.setOnDismissListener { onHideList() }
        }
        deviceListPopupWindow!!.showAtLocation(connect_help, Gravity.LEFT or Gravity.TOP, (SCREEN_WIDTH - width) / 2, (SCREEN_HEIGHT - height) / 2)
        val changeAttributes = window.attributes
        changeAttributes.alpha = 0.6f
        window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
        window.attributes = changeAttributes

    }

    private fun onHideList() {
        isListMode = false
        val changeAttributes = window.attributes
        changeAttributes.alpha = 1f
        window.attributes = changeAttributes
    }

    fun getPercentHeightToPx(percent: Float): Int {
        return (percent * SCREEN_HEIGHT).toInt()
    }

    fun getPercentWidthToPx(percent: Float): Int {
        return (percent * SCREEN_WIDTH).toInt()
    }

}
